#pragma once
//============================================================================
// Copyright (C) 2003-2013 Brett R. Jones 
// All Rights Reserved
//
// You may redistribute and/or modify for non commercial and commercial uses 
// provided this copyright notice remains in place and is not modified
//
// This code is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
// brettjones1900@gmail.com
// http://www.p2panarchy.com
//============================================================================
#include <VxUtilLib/VxTimer.h>

#define VXSKT_INFO_SAMPLE_CNT 10
class VxSktSampleInfo
{
public:
	F64			m_dTime;
	U32			m_u32Bytes;
};

class VxSktThrottle
{
public:
	//=== constructor ===//
	VxSktThrottle();

    //=== destructor ===//
    virtual ~VxSktThrottle();

	//=== public methods ===//
	//! return true if throttle is enabled
	BOOL	IsThrottleEnabled( void )				{ return m_bEnableThrottle;}
	//! set throttle enable state
	void	EnableThrottle( BOOL bEnable = true )	{ m_bEnableThrottle = bEnable;}

	//! set receive speed limit in kilobytes per second
	void	SetRxBandwidthLimitKbs( F32 dKbs )		{ m_f32RxSpeedLimit = dKbs; }
	//! set transmit speed limit in kilobytes per second
	void	SetTxBandwidthLimitKbs( F32 dKbs )		{ m_f32TxSpeedLimit = dKbs; }
	//! if transmit speed limit reached return true
	BOOL	TxBandwidthLimitReached()				{ return( m_f32TxSpeedLimit && ( GetTxSpeedKbs() > m_f32TxSpeedLimit ))?1:0; }
	//! if receive speed limit reached return true
	BOOL	RxBandwidthLimitReached()				{ return( m_f32RxSpeedLimit && ( GetRxSpeedKbs() > m_f32RxSpeedLimit ))?1:0; }

	//! get bytes sent	
	virtual S64		GetBytesSent( void )			{ return m_s64BytesTxed; }
	//! get packets sent	
	virtual S64		GetPacketsSent( void )			{ return m_s64TxPktCnt; }
	//! get bytes received	
	virtual S64		GetBytesRecieved( void )		{ return m_s64BytesRxed; }
	//! get packets sent	
	virtual S64		GetPacketsRecieved( void )		{ return m_s64RxPktCnt; }

	//! reset all statistics
	virtual void	ResetStatistics( void );
	//! reset just receive statistics
	virtual void	ResetRxStatistics( void );
	//! reset just send statistics
	virtual void	ResetTxStatistics( void );
	//! get transmit speed in bits per second
	virtual F32		GetTxSpeed( void )				{ return m_f32TxCurrentSpeed;}
	//! get transmit speed in kilobits per second
	virtual F32		GetTxSpeedKbs( void )			{ return m_f32TxCurrentSpeed/1000.0f;}
	//! get receive speed in bits per second
	virtual F32		GetRxSpeed( void )				{ return m_f32RxCurrentSpeed;}
	//! get receive speed in kilobits per second
	virtual F32		GetRxSpeedKbs( void )			{ return m_f32RxCurrentSpeed/1000.0f;}

	//! packet was sent
	virtual void	TxedPkt( int iPktLen );
	//! packet was received
	virtual void	RxedPkt( int iPktLen );
	//! packet could not be sent
	virtual void	DroppedTxedPkt( int iPktLen );
	//! packet could not be received
	virtual void	DroppedRxedPkt( int iPktLen );
	//! update current transmit speed
	virtual void	UpdateTxSpeed( void )			{m_f32TxCurrentSpeed = (F32)((F64)m_iTxSamplesBytes/m_oTxTimer.ElapsedSec());}
	//! update current transmit speed
	virtual void	UpdateRxSpeed( void )			{m_f32RxCurrentSpeed = (F32)((F64)m_iRxSamplesBytes/m_oRxTimer.ElapsedSec());}

protected:
	//=== vars == //
	BOOL			m_bEnableThrottle;
	VxTimer			m_oTxTimer;
	VxTimer			m_oRxTimer;

	//statistics
	F32				m_f32TxCurrentSpeed;		// current tx speed in bytes per second
	F32				m_f32TxSpeedLimit; 
	F32				m_f32RxCurrentSpeed;		// current tx speed in bytes per second
	F32				m_f32RxSpeedLimit;			
	int				m_iTxSamplesCnt;			// number of sent packets in samples
	int				m_iRxSamplesCnt;			// number of recieved packets in samples
	int				m_iTxSamplesBytes;			// total bytes in tx sample buffers
	int				m_iRxSamplesBytes;			// total bytes in rx sample buffers

	S64				m_s64BytesTxed;
	S64				m_s64BytesRxed;

	S64				m_s64TxPktsDropped;
	S64				m_s64RxPktsDropped;
	S64				m_s64TxPktCnt;
	S64				m_s64RxPktCnt;

};

